/*
 * 工具类-解析json配置文件 且 获取数据库字段信息
 *
 * VERSION  DATE        BY              REASON
 * -------- ----------- --------------- ------------------------------------------
 * 1.00     2014.07.24  wuxiaogang      程序・发布
 * 2.00     2015.01.20  wuxiaogang      程序・更新  新增 jsplen,isformat,baseColumns,baseColumnsJspNeed
 * -------- ----------- --------------- ------------------------------------------
 * Copyright 2014 easycode System. - All Rights Reserved.
 *
 */
package cn.com.softvan.easycode.utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;

import cn.com.softvan.common.IOHelper;
import cn.com.softvan.common.StrUtils;
import cn.com.softvan.easycode.bean.ColumsBean;
import cn.com.softvan.easycode.bean.ConfigBean;
import cn.com.softvan.easycode.bean.TableBean;
import cn.com.softvan.easycode.bean.TableExtBean;
import cn.com.softvan.easycode.utils.jdbc.JdbcUtils;
/**
 * 工具类-解析json配置文件 且 获取数据库字段信息
 * @author wuxiaogang 
 *
 */
public class ConfigJsonAndDbColumsUtils {
	/**
	 * 解析配置文件获取配置信息
	 * @param config_file
	 * @return
	 */
	public static List<ConfigBean> getConfigBeans(String config_file){
		List<ConfigBean> configBeans=new ArrayList<ConfigBean>();
		try {
			//获取配置信息
			String cinfo=IOHelper.readFileData(config_file);
			System.out.println(cinfo.indexOf("["));
			if(cinfo.indexOf("[")!=0){
				//System.out.println("===数据开头有垃圾字符=干掉===");
				cinfo="["+cinfo.substring(cinfo.indexOf("[")+1, cinfo.length());
			}
			System.out.println("==="+cinfo+"===");
			//转为json对象 //获取按模块分类的配置数组数据
			JSONArray moduleArray=JSONArray.fromObject(cinfo);
			System.out.println(moduleArray);
			if(moduleArray!=null){
				for(int i=0;i<moduleArray.size();i++){
					try {
						ConfigBean config=new ConfigBean();
						JSONObject moduleObject=moduleArray.getJSONObject(i);
						//---1---
						config.setAuther(getJsonInfo(moduleObject,"auther"));//开发者
						config.setJsplen(getJsonInfo(moduleObject,"jsplen"));//jsp文件截取action名称字符个数
						config.setIsformat(getJsonInfo(moduleObject,"isformat"));//根据数据库生成的代码是否格式化 如 del_flag 格式化 后delFlag
						config.setRidprefixlen(getJsonInfo(moduleObject,"ridprefixlen"));//去除前缀字符的个数  str=1234 ridprefixlen=2 str=34
						config.setBasepackage(getJsonInfo(moduleObject,"basepackage"));//项目 最基本的包  路径 一般到域名
						config.setCopyright(getJsonInfo(moduleObject,"copyright"));//项目版权信息
						config.setJavaDirUrl(getJsonInfo(moduleObject,"javadir"));//java文件根目录
						config.setResourcesDirUrl(getJsonInfo(moduleObject,"resourcesdir"));//资源文件根目录
						config.setWebAppDir(getJsonInfo(moduleObject,"webappdir"));//web项目根目录
						config.setThisJspDir(getJsonInfo(moduleObject,"thisjspdir"));//当前模块jsp存储目录 相对webAppDir的子目录 用.分割
						config.setDb(getJsonInfo(moduleObject,"db"));//数据库名称
						config.setPackageInfo(getJsonInfo(moduleObject,"packageinfo"));//包说明
						config.setBeanPackage(getJsonInfo(moduleObject,"bean"));//bean类的包路径
						config.setDaointerPackage(getJsonInfo(moduleObject,"daointer"));//dao接口包路径
						config.setEntityPackage(getJsonInfo(moduleObject,"entity"));//entity类包路径
						config.setXmlPackage(getJsonInfo(moduleObject,"xml"));//mybatis xml 文件夹路径
						config.setServicePackage(getJsonInfo(moduleObject,"service"));//service类包路径
						config.setActionPackage(getJsonInfo(moduleObject,"action"));//action类包路径
						config.setSpringDaoXmlExtends(getJsonInfo(moduleObject,"springdaoxmlextends"));//spring dao xml 继承 bean设定
						config.setSpringServiceXmlExtends(getJsonInfo(moduleObject,"springservicexmlextends"));//spring service xml 继承 bean设定
						config.setSpringActionXmlExtends(getJsonInfo(moduleObject,"springactionxmlextends"));//spring action xml 继承 bean设定
						config.setStrutsXmlExtends(getJsonInfo(moduleObject,"strutsxmlextends"));//struts 包 xml 继承 bean设定
						config.setStrutsDefaultInterceptor(getJsonInfo(moduleObject,"strutsdefaultinterceptor"));//struts 包 默认 过滤器设定
						config.setStrutsNamespace(getJsonInfo(moduleObject,"strutsnamespace"));//struts 包  访问路径
						config.setIsBean(getJsonInfo(moduleObject,"isbean"));//是否生成bean 0否 1是设定
						config.setIsEntity(getJsonInfo(moduleObject,"isentity"));//是否生成entity 0否 1是设定
						config.setIsDaoInter(getJsonInfo(moduleObject,"isdaointer"));//是否生成dao接口 0否 1是设定
						config.setIsMybatisXml(getJsonInfo(moduleObject,"ismybatisxml"));//是否生成mybatis xml 文件 0否 1是设定
						config.setIsService(getJsonInfo(moduleObject,"isservice"));//是否生成业务处理类 0否 1是设定
						config.setIsAction(getJsonInfo(moduleObject,"isaction"));//是否生成action类 0否 1是设定
						config.setIsJsp(getJsonInfo(moduleObject,"isjsp"));//是否生成jsp页面文件 0否 1是设定
						config.setIsStrutsXml(getJsonInfo(moduleObject,"isstrutsxml"));//是否生成struts xml配置文件 0否 1是设定
						config.setDelColumns(getJsonInfo(moduleObject,"delcolumns"));//逻辑删除字段
						config.setActionJoin(getJsonInfo(moduleObject,"actionjoin"));//Action 访问连接符
						//基础字段==已经存在于baseBean和baseEntity中的字段
						JSONArray basecolumnsArray=getJsonArray(moduleObject,"basecolumns");
						if(basecolumnsArray!=null){
							List<String> basecolumns=new ArrayList<String>();
							for(int n=0;n<basecolumnsArray.size();n++){
								JSONObject basecolumnsObject=basecolumnsArray.getJSONObject(n);
								basecolumns.add(getJsonInfo(basecolumnsObject,"name"));
							}
							config.setBaseColumns(basecolumns);
						}
						//JSP中需要显示的基础字段 列表==已经存在于baseBean和baseEntity中的字段 
						JSONArray baseColumnsJspNeedArray=getJsonArray(moduleObject,"basecolumnsjspneed");
						if(baseColumnsJspNeedArray!=null){
							List<String> baseColumnsJspNeedList=new ArrayList<String>();
							for(int n=0;n<baseColumnsJspNeedArray.size();n++){
								JSONObject baseColumnsJspNeedObject=baseColumnsJspNeedArray.getJSONObject(n);
								baseColumnsJspNeedList.add(getJsonInfo(baseColumnsJspNeedObject,"name"));
							}
							config.setBaseColumnsJspNeed(baseColumnsJspNeedList);
						}
						//数据库新增默认字段    这些字段新增时不需要前台传入值  使用固定值
						JSONArray dbInsertDefaultArray=getJsonArray(moduleObject,"dbinsertdefault");
						if(dbInsertDefaultArray!=null){
							Map<String,String> map=new HashMap<String,String>();
							for(int n=0;n<dbInsertDefaultArray.size();n++){
								JSONObject dbInsertDefaultObject=dbInsertDefaultArray.getJSONObject(n);
								map.put( getJsonInfo(dbInsertDefaultObject,"name"), getJsonInfo(dbInsertDefaultObject,"val"));
							}
							config.setDbInsertDefault(map);
						}
						//数据库更新默认字段    这些字段更新  使用固定格式
						JSONArray dbUpdateDefaultArray=getJsonArray(moduleObject,"dbupdatedefault");
						if(dbUpdateDefaultArray!=null){
							Map<String,String> map=new HashMap<String,String>();
							for(int n=0;n<dbUpdateDefaultArray.size();n++){
								JSONObject dbUpdateDefaultObject=dbUpdateDefaultArray.getJSONObject(n);
								map.put( getJsonInfo(dbUpdateDefaultObject,"name"), getJsonInfo(dbUpdateDefaultObject,"val"));
							}
							config.setDbUpdateDefault(map);
						}
						//数据库新增时 无需写入数据库值的字段
						JSONArray dbInsertNotArray=getJsonArray(moduleObject,"dbinsertnot");
						if(dbInsertNotArray!=null){
							Map<String,String> map=new HashMap<String,String>();
							for(int n=0;n<dbInsertNotArray.size();n++){
								JSONObject dbInsertNotObject=dbInsertNotArray.getJSONObject(n);
								map.put(getJsonInfo(dbInsertNotObject,"name"), getJsonInfo(dbInsertNotObject,"name"));
							}
							config.setDbInsertNot(map);
						}
						//数据库更新时 无需写入数据库值的字段
						JSONArray dbUpdateNotArray=getJsonArray(moduleObject,"dbupdatenot");
						if(dbUpdateNotArray!=null){
							Map<String,String> map=new HashMap<String,String>();
							for(int n=0;n<dbUpdateNotArray.size();n++){
								JSONObject dbUpdateNotObject=dbUpdateNotArray.getJSONObject(n);
								map.put(getJsonInfo(dbUpdateNotObject,"name"), getJsonInfo(dbUpdateNotObject,"name"));
							}
							config.setDbUpdateNot(map);
						}
						//---2---
						JSONArray tablesArray=getJsonArray(moduleObject,"tables");
						if(tablesArray!=null){
							List<TableBean> tableBeans=new ArrayList<TableBean>();
							for(int n=0;n<tablesArray.size();n++){
								TableBean tableBean=new TableBean();
								JSONObject tablesObject=tablesArray.getJSONObject(n);
								//--3----
								tableBean.setDbName(config.getDb());//数据库名
								tableBean.setTableName(getJsonInfo(tablesObject,"table"));//数据库表名
								tableBean.setTableNote(getJsonInfo(tablesObject,"note"));//数据库中文备注
								tableBean.setClassName(getJsonInfo(tablesObject,"classname"));//数据库生成的类名(基本类名 不含 Bean Dao 等前缀与后缀)
								tableBean.setServiceName(getJsonInfo(tablesObject, "servicename"));//service业务处理类名称
								tableBean.setActionName(getJsonInfo(tablesObject, "actionname"));//action类名称
								
								//生成后列表显示字段
								JSONArray showColumnsArray=getJsonArray(tablesObject,"showcolumns");
								if(showColumnsArray!=null){
 									List<ColumsBean> showColumnsList=new ArrayList<ColumsBean>();
									for(int y=0;y<showColumnsArray.size();y++){
										ColumsBean columsBean=new ColumsBean();
										JSONObject showColumnsObject=showColumnsArray.getJSONObject(y);
										columsBean.setColmd(getJsonInfo(showColumnsObject,"colmd"));//显示列宽度
										columsBean.setName(getJsonInfo(showColumnsObject,"name"));//显示列名称
										columsBean.setDbcolumns(getJsonInfo(showColumnsObject,"dbcolumns"));//显示列字段
										showColumnsList.add(columsBean);
									}
									tableBean.setShowColumns(showColumnsList);
								}
								
								//编辑页面特殊控件字段
								JSONArray specialcolumnsArray=getJsonArray(tablesObject,"specialcolumns");
								if(specialcolumnsArray!=null){
									Map<String,String> map=new HashMap<String,String>();
									for(int y=0;y<specialcolumnsArray.size();y++){
										JSONObject specialcolumnsObject=specialcolumnsArray.getJSONObject(y);
										map.put(getJsonInfo(specialcolumnsObject,"dbcolumns"), getJsonInfo(specialcolumnsObject,"type"));//显示列字段 : 字段编辑控件类型0单行文本 1多行文本2日期控件3单项下拉选择框4多项下拉选择框5单项项6多选项
									}
									tableBean.setSpecialcolumns(map);
								}
								
								//TODO  获取数据库字段列表
								tableBean.setColums(getColumsBeans(tableBean));
								//--4----
								//bean
								tableBean.setBeanExt(getExtBean(tablesObject,"beanext"));
								//entity
								tableBean.setEntityExt(getExtBean(tablesObject,"entityext"));
								//dao
								tableBean.setDaointerExt(getExtBean(tablesObject,"daointerext"));
								//service interface
								tableBean.setServiceInterExt(getExtBean(tablesObject,"serviceinterext"));
								//service impl
								tableBean.setServiceExt(getExtBean(tablesObject,"serviceext"));
								//action
								tableBean.setActionExt(getExtBean(tablesObject,"actionext"));
								tableBean.setSpringDaoXmlExtends(getJsonInfo(tablesObject,"springdaoxmlextends"));//spring dao xml 继承 bean设定
								tableBean.setSpringServiceXmlExtends(getJsonInfo(tablesObject,"springservicexmlextends"));//spring service xml 继承 bean设定
								tableBean.setSpringActionXmlExtends(getJsonInfo(tablesObject,"springactionxmlextends"));//spring action xml 继承 bean设定
								tableBean.setIsBean(getJsonInfo(tablesObject,"isbean"));//是否生成bean 0否 1是设定
								tableBean.setIsEntity(getJsonInfo(tablesObject,"isentity"));//是否生成entity 0否 1是设定
								tableBean.setIsDaoInter(getJsonInfo(tablesObject,"isdaointer"));//是否生成dao接口 0否 1是设定
								tableBean.setIsMybatisXml(getJsonInfo(tablesObject,"ismybatisxml"));//是否生成mybatis xml 文件 0否 1是设定
								tableBean.setIsService(getJsonInfo(tablesObject,"isservice"));//是否生成业务处理类 0否 1是设定
								tableBean.setIsAction(getJsonInfo(tablesObject,"isaction"));//是否生成action类 0否 1是设定
								tableBean.setIsJsp(getJsonInfo(tablesObject,"isjsp"));//是否生成jsp页面文件 0否 1是设定
								tableBean.setIsStrutsXml(getJsonInfo(tablesObject,"isstrutsxml"));//是否生成struts xml配置文件 0否 1是设定
								//--add list
								tableBeans.add(tableBean);
							}
							config.setTables(tableBeans);
						}
						//---5---
						//bean
						config.setBeanExt(getExtBean(moduleObject,"beanext"));
						//entity
						config.setEntityExt(getExtBean(moduleObject,"entityext"));
						//dao
						config.setDaointerExt(getExtBean(moduleObject,"daointerext"));
						//service interface
						config.setServiceInterExt(getExtBean(moduleObject,"serviceinterext"));
						//service impl
						config.setServiceExt(getExtBean(moduleObject,"serviceext"));
						//action
						config.setActionExt(getExtBean(moduleObject,"actionext"));
						//TODO ----------------
						configBeans.add(config);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return configBeans;
	}
	/**
	 * 获取表字段信息列表
	 * @param tableBean
	 * @return
	 */
	public static List<ColumsBean> getColumsBeans(TableBean tableBean){
		List<ColumsBean> columsBeans=new ArrayList<ColumsBean>();
		Connection conn = null;
		Statement smt = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getInstance().getConnection();
			String sql="select t.COLUMN_NAME," +
					"t.COLUMN_COMMENT," +
					"t.COLUMN_DEFAULT," +
					"t.DATA_TYPE," +
					"t.COLUMN_KEY," +
					"t.CHARACTER_MAXIMUM_LENGTH," +
					"t.IS_NULLABLE " +
					"from information_schema.`COLUMNS` t " +
					"where t.TABLE_SCHEMA='"+tableBean.getDbName()+"' " +
							"and " +
							"t.TABLE_NAME='"+tableBean.getTableName()+"'";
			System.out.println(sql);
			smt = conn.createStatement();
			rs = smt.executeQuery(sql);
			rs.last(); //移到最后一行
			if(rs.getRow()==0){
				System.err.println("----"+tableBean.getDbName()+"."+tableBean.getTableName()+" 未找到--请检查-数据库名(包括连接池地址)与表名是否配置错误!");
			}
			rs.beforeFirst();
			while(rs.next()){
				ColumsBean columsBean=new ColumsBean();
				columsBean.setColumsName(StrUtils.toLowerCase(rs.getString(1)));
				columsBean.setColumsNote(StrUtils.replaceAll(rs.getString(2), "\n", ""));
				columsBean.setColumsValue(rs.getString(3));
				columsBean.setColumsType(rs.getString(4));
				columsBean.setColumsKey(rs.getString(5));
				columsBean.setColumsLength(rs.getString(6));
				columsBean.setColumsIsNull(rs.getString(7));
				columsBeans.add(columsBean);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			try {
				smt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return columsBeans;
	}
	/**
	 * 获取json对象的具体数据
	 * @param jsonObject
	 * @param key
	 * @return
	 */
	private static String getJsonInfo(JSONObject jsonObject,String key){
		String info=null;
		try {
			if(jsonObject!=null){
				info=jsonObject.getString(key);
				if(info!=null){
					info=StringUtils.trim(info);
				}
			}
		} catch (Exception e) {
		}
		return info;
	}
	/**
	 * 获取json对象的具体数据
	 * @param jsonObject
	 * @param key
	 * @return
	 */
	private static JSONArray getJsonArray(JSONObject jsonObject,String key){
		JSONArray info=null;
		try {
			if(jsonObject!=null){
				info=jsonObject.getJSONArray(key);
			}
		} catch (Exception e) {
		}
		return info;
	}
	/**
	 * 获取json对象中 ext 对象信息
	 * @param jsonOject
	 * @param key
	 * @return
	 */
	private static TableExtBean getExtBean(JSONObject jsonOject,String key){
		TableExtBean ext=new TableExtBean();
		try {
			//扩展信息
			JSONObject dataObject=jsonOject.getJSONObject(key);
			try {
				JSONArray importArray=dataObject.getJSONArray("importclass");
				if(importArray!=null){
					List<String> importList=new ArrayList<String>();
					for(int m=0;m<importArray.size();m++){
						try {
							JSONObject	importObject=importArray.getJSONObject(m);
							importList.add(getJsonInfo(importObject, "path"));
						} catch (Exception e) {
						}
					}
					ext.setImportclass(importList);
				}
			} catch (Exception e) {
			}
			ext.setExtendsClass(getJsonInfo(dataObject,"extends"));
			ext.setImplClass(getJsonInfo(dataObject,"impl"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ext;
	}
}
